package cn.hinglo.gameclaw.alipay.service;

import cn.hinglo.gameclaw.admin.service.MoneyService;
import cn.hinglo.gameclaw.admin.service.MorderService;
import cn.hinglo.gameclaw.alipay.utils.AlipayUtils;
import cn.hinglo.gameclaw.alipay.utils.WeixinUtils;
import cn.hinglo.gameclaw.data.utils.FieldUtils;
import cn.hinglo.gameclaw.user.bean.Money;
import cn.hinglo.gameclaw.user.bean.Morder;
import cn.hutool.core.date.DateUtil;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @createTime: 2018/5/22
 * @author: HingLo
 * @description: 支付宝下单信息管理
 */
@Service
@Slf4j
public class RechargeOrderService {

    private static final String NOTIFY_URL_ALIPAY = "/pay/r/moneyNotifyAlipay";
    private static final String NOTIFY_URL_WEIXIN = "/pay/r/moneyNotifyWeixin";
    @Autowired
    private MoneyService moneyService;
    @Autowired
    private MorderService morderService;

    //************************************支付宝充值****************************************

    /**
     * 支付宝充值统一下单
     *
     * @param moneyId 充值面板的唯一Id
     * @param userId  用户的Id
     * @return 返回值
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public String moneyAlipayOrderService(String moneyId, String userId) {
        //生成一个订单
        Morder morder = createRechargeOrder(moneyId, userId, FieldUtils.PAYMENT_1);
        if (morder == null) {
            return null;
        }

        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

        //对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body。
        model.setBody(morder.getBody());
        //商品的标题/交易标题/订单标题/订单关键字等。
        model.setSubject(morder.getSubject());
        //订单的编号
        model.setOutTradeNo(morder.getId());
        //订单有效期该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        model.setTimeoutExpress("30m");
        //充值的金额
        model.setTotalAmount(morder.getNum().toString());
        // 销售产品码，商家和支付宝签约的产品码，为固定值  QUICK_MSECURITY_PAY
        model.setProductCode("QUICK_MSECURITY_PAY");
        // 商品主类型 :0-虚拟类商品,1-实物类商品
        model.setGoodsType("0");
        log.info("支付宝充值下单信息：{}", model);
        return AlipayUtils.order(model, FieldUtils.URL + NOTIFY_URL_ALIPAY);
    }

    /**
     * 支付宝充值结果通知信息
     *
     * @param request request
     * @return 是否充值成
     */
    public boolean moneyAlipayNotifyService(HttpServletRequest request) {
        Map<String, String> result = AlipayUtils.validate(request);
        if (result != null) {
            String trade_status = result.get("trade_status");
            if ("TRADE_SUCCESS".equals(trade_status)) {
                //获取订单号码
                String orderId = result.get("out_trade_no");
                //付款时间
                String pd = result.get("gmt_payment");
                Date payDate = DateUtil.parse(pd);
                //支付的支付宝账号
                String payAccount = result.get("buyer_logon_id");
                log.info("支付宝充值通知信息：订单编号->{}", orderId);
                return morderService.updateMorderService(orderId, payDate, payAccount);
            }
            return false;

        } else {
            log.info("支付宝充值通知信息校验失败");
            return false;
        }
    }

    //*****************************************************微信充值统一下单******************************************

    @Transactional(rollbackFor = RuntimeException.class)
    public String moneyWeixinOrderService(String moneyId, String userId, String ip) {
        //生成一个订单
        Morder morder = createRechargeOrder(moneyId, userId, FieldUtils.PAYMENT_2);
        if (morder == null) {
            return null;
        }
        Map<String, String> data = new HashMap<>(7);
        data.put("body", morder.getBody());
        data.put("out_trade_no", morder.getId());
        // 货币类型
        data.put("fee_type", "CNY");
        // 支付金额
        data.put("total_fee", String.valueOf(morder.getNum() * 100));
        // 用户端实际ip
        data.put("spbill_create_ip", ip);
        //回调通知URL
        data.put("notify_url", FieldUtils.URL + NOTIFY_URL_WEIXIN);
        // 此处指定为APP 支付
        data.put("trade_type", "APP");
        try {
            log.info("微信充值下单信息：{}", data);
            return WeixinUtils.order(data);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("订单创建失败");
        }
    }

    /**
     * 微信支付结果过通知
     *
     * @param request
     * @return
     */

    public boolean moneyWeixinNotifyService(HttpServletRequest request) {
        try {
            Map<String, String> result = WeixinUtils.validate(request);
            if (result == null) {
                return false;
            } else {
                // 业务支付成功否
                String res = result.get("return_code");
                if ("SUCCESS".equals(res)) {
                    String orderId = result.get("out_trade_no");
                    //付款时间
                    String pd = result.get("time_end");
                    Date payDate = DateUtil.parse(pd);
                    //微信支付得不到微信支付的账号 默认为null
                    String payAccount = "";
                    log.info("微信充值通知信息：订单编号->{}", orderId);
                    return morderService.updateMorderService(orderId, payDate, payAccount);
                } else {
                    return false;
                }


            }
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 统一生成一充值订单
     *
     * @param moneyId 充值面板的唯一Id
     * @param userId  用户dId
     * @param type    支付方式
     * @return 返回结果
     */
    private Morder createRechargeOrder(String moneyId, String userId, int type) {
        Money money = moneyService.findByIdMoneyService(moneyId);
        if (money == null) {
            throw new RuntimeException("充值信息不存在或者活动已经过期");
        }
        //生成一个订单
        return morderService.addService(money, userId, type);

    }
}
